package com.luych.toolbox.gateway.center.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.luych.toolbox.common.enums.MicroInstanceStatus;
import com.luych.toolbox.common.feign.view.gateway.center.InstanceView;
import com.luych.toolbox.common.feign.view.gateway.center.ServiceView;
import com.netflix.discovery.EurekaClientConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Api(tags = "微服务管理")
@RestController
@RequestMapping("/api/service")
public class ServiceController {

    private final EurekaClientConfig eurekaClientConfig;

    @Autowired
    public ServiceController(EurekaClientConfig eurekaClientConfig) {
        this.eurekaClientConfig = eurekaClientConfig;
    }

    @ApiOperation("查询微服务列表")
    @GetMapping()
    public List<ServiceView> list() {
        String eurekaRegion = eurekaClientConfig.getRegion();
        String[] eurekaZones = eurekaClientConfig.getAvailabilityZones(eurekaRegion);
        List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(eurekaZones[0]);

        String httpUrl = eurekaUrls.get(0) + "/apps";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(httpUrl, String.class);

        JsonNode rootNode;
        try {
            rootNode = new ObjectMapper().readTree(responseEntity.getBody());
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        List<ServiceView> appViews = new ArrayList<>();
        JsonNode appNodes = rootNode.get("applications").get("application");
        for (JsonNode appNode : appNodes) {
            ServiceView appView = new ServiceView();
            appView.setName(appNode.get("name").asText());

            List<InstanceView> instanceViews = new ArrayList<>();
            JsonNode instanceNodes = appNode.get("instance");
            for (JsonNode instanceNode : instanceNodes) {
                InstanceView instanceView = new InstanceView();
                instanceView.setInstanceId(instanceNode.get("instanceId").asText());
                instanceView.setHostName(instanceNode.get("hostName").asText());
                instanceView.setIpAddr(instanceNode.get("ipAddr").asText());
                instanceView.setStatus(MicroInstanceStatus.valueOf(instanceNode.get("status").asText()));
                if (instanceNode.get("port").get("@enabled").asBoolean()) {
                    instanceView.setHttpPort(instanceNode.get("port").get("$").asInt());
                }
                if (instanceNode.get("securePort").get("@enabled").asBoolean()) {
                    instanceView.setHttpsPort(instanceNode.get("securePort").get("$").asInt());
                }
                instanceView.setUpTimestamp(instanceNode.get("leaseInfo").get("serviceUpTimestamp").asLong());
                instanceViews.add(instanceView);
            }
            appView.setInstances(instanceViews);
            appViews.add(appView);
        }
        return appViews;
    }
}
